package keeto.com.vn.classified.manager;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.Vector;
import keeto.com.vn.classfied.model.Area;
import keeto.com.vn.classfied.model.Category;
import keeto.com.vn.classified.config.IConstant;
import keeto.com.vn.classified.config.ReleaseConfig;
import keeto.com.vn.classified.database.DBString;
import keeto.com.vn.classified.database.SabonaDBHelper;
import keeto.com.vn.classified.database.SabonaDataBase;

import org.json.JSONException;
import org.json.JSONObject;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.util.Log;
import android.content.SharedPreferences;
import android.util.Log;


public class IAManager implements IConstant {

	SabonaDBHelper dbHelper;
	SabonaDataBase db;
	
	static volatile IAManager self = null;
	private static final Object locker = new Object();
	Context context;
	public static String SP_NAME = "MY_INFO";
	private static String SP_MY_AREA = "my_area";
	private static String SP_CATEGORY_LANGUAGE = "category_language";
	private static String SP_AREA_VERSION = "area_version";
	private static String SP_CATEGORY_VERSION = "category_version";
	private static String SP_ALL_VERSION = "all_version";

	public IAManager(Context context) {
		this.context = context;

		dbHelper = SabonaDBHelper.getInstance(context, true); // tell the IMDBHelper that
													// it is a meta data
		db = SabonaDataBase.getInstance(dbHelper);
		importMetaData();
		if (getMyArea() == null) {
			saveMyArea(ReleaseConfig.DEFAULT_MY_AREA);
		}
	}

	public static IAManager getInstance(Context context) {

		if (null == self) {
			synchronized (locker) {
				if (null == self) {
					self = new IAManager(context);
				}
			}
		}
		return self;
	}

	private boolean checkDataVersion(String type, int version) {
		SharedPreferences settings = context.getSharedPreferences(SP_NAME, 0);
		int nowVersion = settings.getInt(type, 0);
		int newVersion = Integer.valueOf(version);
		if (newVersion != nowVersion) {
			return false;
		}
		return true;
	}

	private void updateVersion(String type, int newVersion) {
		SharedPreferences settings = context.getSharedPreferences(SP_NAME, 0);
		settings.edit().putInt(type, newVersion).commit();
	}

	private void importMetaData() {
		String dbPath = "/data/data/" + context.getPackageName()
				+ "/databases/" + DBString.IA_META_DB_NAME;
		File dbFile = new File(dbPath);
		boolean needCopyMetaDb = false;

		if (!dbFile.exists()) {
			needCopyMetaDb = true;
			dbFile.mkdirs();
		} else {
			if (!checkDataVersion(SP_ALL_VERSION, DBString.DB_VERSION)) {
				needCopyMetaDb = true;
			}
		}

		if (needCopyMetaDb) {
			try {
				Log.e("COPY DATABSE", "START " + System.currentTimeMillis());
				InputStream myInput = context.getAssets().open(
						"databases/" + DBString.IA_META_DB_NAME);
				
				OutputStream myOutput = new FileOutputStream(dbPath);
				byte[] buffer = new byte[1024];
				int length;
				while ((length = myInput.read(buffer)) > 0) {
					myOutput.write(buffer, 0, length);
				}
				// Close the streams
				myOutput.flush();
				myOutput.close();
				myInput.close();
				Log.e("COPY DATABSE", "SUCESS " + System.currentTimeMillis());
			} catch (Exception ex) {
				ex.printStackTrace();
			}
			updateVersion(SP_ALL_VERSION,DBString.DB_VERSION);
		}
	}

	private void parserArea() {

		String[] keys = { "remote_id", "parent_remote_id", "name", " alias1",
				" alias2", "abbreviation", "sort", "state", "level"};
		try {
			AssetManager assetManager = context.getResources().getAssets();
			InputStream stream = assetManager.open("test/area.txt");
			InputStreamReader streamReader = new InputStreamReader(stream);
			BufferedReader bufferReader = new BufferedReader(streamReader);
			String cl = bufferReader.readLine();
			int newVersion = Integer.valueOf(cl);
			if (checkDataVersion(SP_AREA_VERSION, newVersion)) {
				return;
			}
			db.getDb().beginTransaction();
			try {
				db.delete("IAArea", null, null);
				int j = 0;
				while ((cl = bufferReader.readLine()) != null) {
					j++;
					String[] values = cl.split(";");
					ContentValues contentValues = new ContentValues();
					if (keys.length != values.length) {
						continue;
					}
					for (int i = 0; i < keys.length; i++) {
						contentValues.put(keys[i], values[i]);
					}
					Log.e("PARSE AREA",
							values[2] + " " + System.currentTimeMillis());
					db.insert("IAArea", null, contentValues);
					Log.e("PARSE AREA",
							values[2] + " " + System.currentTimeMillis());
				}
				if (getMyArea() == null) {
					// what does 163 mean? this code for test. set the default
					// area = Jakarta
					saveMyArea("1");
				}
				updateVersion(SP_AREA_VERSION, newVersion);
				db.getDb().setTransactionSuccessful();
			} catch (IOException e) {
			} finally {
				// if exceptions were thrown,
				// db.getDb().setTransactionSuccessful();
				// will not be executed, the transaction will be rolled back

				try {
					db.getDb().endTransaction();
				} catch (NullPointerException e) {

				}
			}
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
		}
	}

	private void parserMulitLanguage() {
		AssetManager assetManager = context.getResources().getAssets();
		String filePath = "test/multi_language";
		try {
			String[] files = assetManager.list(filePath);
			for (String fileName : files) {
				String language = fileName.split("__")[0];
				InputStream inputStream = assetManager.open(filePath + "/"
						+ fileName);
				InputStreamReader streamReader = new InputStreamReader(
						inputStream);
				BufferedReader bufferReader = new BufferedReader(streamReader);
				String cl = bufferReader.readLine();
				int newVersion = Integer.valueOf(cl);
				if (checkDataVersion(SP_CATEGORY_LANGUAGE + language,
						newVersion)) {
					continue;
				}
				db.getDb().beginTransaction();
				try {
					db.delete("IALanguage", null, null);
					while ((cl = bufferReader.readLine()) != null) {
						String[] values = cl.split(";");
						ContentValues contentValues = new ContentValues();
						contentValues.put("category_remote_id", values[0]);
						contentValues.put("language", language);
						contentValues.put("title", values[1]);
						db.insert("IALanguage", null, contentValues);
					}
					updateVersion(SP_CATEGORY_LANGUAGE + language, newVersion);
					db.getDb().setTransactionSuccessful();
				} catch (IOException e) {
				} finally {
					// if exceptions were thrown,
					// db.getDb().setTransactionSuccessful();
					// will not be executed, the transaction will be rolled back
					try {
						db.getDb().endTransaction();
					} catch (NullPointerException e) {

					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void parserCategory() {

		String[] keys = { "remote_id", "parent_remote_id", "publish_template",
				"search_template", "name", "icon", "sort", "state", "isHot",
				"type", "linkId" };
		try {
			AssetManager assetManager = context.getResources().getAssets();
			InputStream inputStream = assetManager.open("test/cate.txt");
			InputStreamReader streamReader = new InputStreamReader(inputStream);
			BufferedReader bufferReader = new BufferedReader(streamReader);
			String cl = bufferReader.readLine();
			int newVersion = Integer.valueOf(cl);
			if (checkDataVersion(SP_CATEGORY_VERSION, newVersion)) {
				return;
			}
			db.getDb().beginTransaction();
			try {
				db.delete("IACategory", null, null);
				while ((cl = bufferReader.readLine()) != null) {
					String[] values = cl.split(";");
					ContentValues contentValues = new ContentValues();
					if (keys.length != values.length) {
						continue;
					}
					for (int i = 0; i < keys.length; i++) {
						contentValues.put(keys[i], values[i]);
					}
					Log.e("PARSE CATEGORY",
							values[4] + System.currentTimeMillis());
					db.insert("IACategory", null, contentValues);
					Log.e("PARSE CATEGORY",
							values[4] + System.currentTimeMillis());
				}
				updateVersion(SP_CATEGORY_VERSION, newVersion);
				db.getDb().setTransactionSuccessful();
			} catch (IOException e) {
			} finally {
				// if exceptions were thrown,
				// db.getDb().setTransactionSuccessful();
				// will not be executed, the transaction will be rolled back
				try {
					db.getDb().endTransaction();
				} catch (NullPointerException e) {

				}
			}
			parserMulitLanguage();
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
		}
	}

	/*
	 * private void saveCategory() {
	 * 
	 * }
	 * 
	 * private void saveArea() {
	 * 
	 * }
	 * 
	 * public void saveAd() {
	 * 
	 * }
	 * 
	 * private void saveTemplate() {
	 * 
	 * }
	 */
	private Category fillCategory(Cursor courser) {
		Category category = new Category();
		category.setHot(courser.getInt(courser.getColumnIndex("isHot")) == 1 ? true
				: false);
		category.setIcon(courser.getString(courser.getColumnIndex("icon")));
		category.setName(courser.getString(courser.getColumnIndex("name")));
		category.setParentRID(courser.getString(courser
				.getColumnIndex("parent_remote_id")));
		category.setPublishTemplate(courser.getString(courser
				.getColumnIndex("publish_template")));
		category.setRemoteId(courser.getString(courser
				.getColumnIndex("remote_id")));
		category.setSearchTemplate(courser.getString(courser
				.getColumnIndex("search_template")));
		category.setSort(courser.getInt(courser.getColumnIndex("sort")));
		category.setState(courser.getInt(courser.getColumnIndex("state")));
		category.setType(courser.getInt(courser.getColumnIndex("type")));
		category.setLinkId(courser.getString(courser.getColumnIndex("linkId")));
		return category;
	}

	public Category getOneCategory(String id) {
		String language = "vi";
		Category category = null;
		Cursor cursor = db.query("IACategory", null, "remote_id=? ",
				new String[] { id }, null, null, null);
		if (cursor.getCount() > 0) {
			cursor.moveToFirst();
			category = fillCategory(cursor);
		}
		cursor.close();
		if ( category != null) {
			Vector<Category> categories = new Vector<Category>();
			categories.add(category);
			setCategoryLanguage(categories, language);
		}
		return category;
	}

	private void setCategoryLanguage(Vector<Category> categories,
			String language) {
		Log.d("TEST M-Language", "setCategoryLanguage = " + language);
		StringBuffer selection = new StringBuffer(
				"language=? AND  category_remote_id IN (");
		String[] selectionArgs = new String[categories.size() + 1];
		Hashtable<String, Category> mapping = new Hashtable<String, Category>();
		int i = 0;
		selectionArgs[0] = language;
		for (Category category : categories) {
			selection.append("?,");
			String id = category.getRemoteId();
			selectionArgs[++i] = id;
			mapping.put(id, category);
		}
		if (categories.size() > 0) {
			selection.deleteCharAt(selection.length() - 1);
		}
		selection.append(")");

		Cursor cursor = db.query("IALanguage", null, selection.toString(),
				selectionArgs, null, null, null);
		Log.d("TEST M-Language", "cursor.getCount() = " + cursor.getCount());
		for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
			String remoteId = cursor.getString(cursor
					.getColumnIndex("category_remote_id"));
			String title = cursor.getString(cursor.getColumnIndex("title"));
			Category category = mapping.get(remoteId);
			category.setName(title);
			Log.d("TEST M-Language", "ID = " + category.getRemoteId()
					+ " Title = " + category.getName());
		}
		cursor.close();
	}

	private Vector<Category> getCategory(String pid, int type) {
		String language = "vi";
		Cursor cursor = db.query("IACategory", null,
				"parent_remote_id=? AND (type=0 OR type=" + type + ")",
				new String[] { pid }, null, null, "sort DESC,remote_id ASC");
		Vector<Category> categories = new Vector<Category>();
		for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
			Category category = fillCategory(cursor);
			Log.e("TAGGGGG", category.getRemoteId()+" + "+ category.getName());
			if (category.getRemoteId().equals("4")
					|| category.getRemoteId().equals("9")
					|| category.getRemoteId().equals("11")
					|| category.getRemoteId().equals("14")
					|| category.getRemoteId().equals("23")
					|| category.getRemoteId().equals("30")
					|| category.getRemoteId().equals("40")
					|| category.getRemoteId().equals("61")
					|| category.getRemoteId().equals("73")
					|| category.getRemoteId().equals("82")
					|| category.getRemoteId().equals("92")
					|| category.getRemoteId().equals("110")
					|| category.getRemoteId().equals("124")
					|| category.getRemoteId().equals("133")) {
				
			} else {
				categories.add(category);
			}
			
		}
		cursor.close();
		setCategoryLanguage(categories,"vi");
		if (pid.equals("5")){
			for (int i=0;i<categories.size();i++){
				if (categories.elementAt(i).getRemoteId().equals("60")){
					categories.remove(i);
					i--;
				}
			}
		}else if (pid.equals("6")){
			for (int i=0;i<categories.size();i++){
				if (categories.elementAt(i).getRemoteId().equals("72")){
					categories.remove(i);
					i--;
				}
			}
		}else if (pid.equals("8")){
			for (int i=0;i<categories.size();i++){
				if (categories.elementAt(i).getRemoteId().equals("91")){
					categories.remove(i);
					i--;
				}
			}
		}else if (pid.equals("10")){
			for (int i=0;i<categories.size();i++){
				if (categories.elementAt(i).getRemoteId().equals("109")){
					categories.remove(i);
					i--;
				}
			}
		}
		return categories;
	}

	public Vector<Category> getViewCategory(String pid) {
		return getCategory(pid, 1);
	}

	public Vector<Category> getPublishCategory(String pid) {
		return getCategory(pid, 2);
	}

	public Vector<Area> getArea(String pid) {
		Cursor cursor = db.query("IAArea", null, "parent_remote_id=?",
				new String[] { pid }, null, null, null);
		Vector<Area> areas = new Vector<Area>();
		for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
			Area area = new Area();
			area.setAbbreviation(cursor.getString(cursor
					.getColumnIndex("abbreviation")));
			area.setAlias1(cursor.getString(cursor.getColumnIndex("alias1")));
			area.setAlias2(cursor.getString(cursor.getColumnIndex("alias2")));
			area.setName(cursor.getString(cursor.getColumnIndex("name")));
			area.setParentRID(cursor.getString(cursor
					.getColumnIndex("parent_remote_id")));
			area.setRemoteId(cursor.getString(cursor
					.getColumnIndex("remote_id")));
			area.setSort(cursor.getInt(cursor.getColumnIndex("sort")));
			area.setState(cursor.getInt(cursor.getColumnIndex("state")));
			area.setIshot((cursor.getInt(cursor.getColumnIndex("ishot")) == 1) ? true : false);
			areas.add(area);
		}
		cursor.close();
		return areas;
	}

	public Vector<Area> getAllArea() {
		Cursor cursor = db.query("IAArea", null, null,
				null, null, null, null);
		Vector<Area> areas = new Vector<Area>();
		for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
			Area area = new Area();
			area.setAbbreviation(cursor.getString(cursor
					.getColumnIndex("abbreviation")));
			area.setAlias1(cursor.getString(cursor.getColumnIndex("alias1")));
			area.setAlias2(cursor.getString(cursor.getColumnIndex("alias2")));
			area.setName(cursor.getString(cursor.getColumnIndex("name")));
			area.setParentRID(cursor.getString(cursor
					.getColumnIndex("parent_remote_id")));
			area.setRemoteId(cursor.getString(cursor
					.getColumnIndex("remote_id")));
			area.setSort(cursor.getInt(cursor.getColumnIndex("sort")));
			area.setState(cursor.getInt(cursor.getColumnIndex("state")));
			area.setIshot((cursor.getInt(cursor.getColumnIndex("ishot")) == 1) ? true : false);
			areas.add(area);
		}
		cursor.close();
		return areas;
	}
	
	public Area getOneArea(String aid) {
		Area area = null;
		Cursor cursor = db.query("IAArea", null, "remote_id=?",
				new String[] { aid }, null, null, null);
		if (cursor.getCount() > 0) {
			cursor.moveToFirst();
			area = new Area();
			area.setAbbreviation(cursor.getString(cursor
					.getColumnIndex("abbreviation")));
			area.setAlias1(cursor.getString(cursor.getColumnIndex("alias1")));
			area.setAlias2(cursor.getString(cursor.getColumnIndex("alias2")));
			area.setName(cursor.getString(cursor.getColumnIndex("name")));
			area.setParentRID(cursor.getString(cursor
					.getColumnIndex("parent_remote_id")));
			area.setRemoteId(cursor.getString(cursor
					.getColumnIndex("remote_id")));
			area.setSort(cursor.getInt(cursor.getColumnIndex("sort")));
			area.setState(cursor.getInt(cursor.getColumnIndex("state")));
			area.setIshot((cursor.getInt(cursor.getColumnIndex("ishot")) == 1) ? true : false);
		}
		cursor.close();
		return area;
	}

	public void saveMyArea(String areaId) {
		SharedPreferences settings = context.getSharedPreferences(SP_NAME, 0);
		Editor edit = settings.edit();
		edit.putString(SP_MY_AREA, areaId);
		edit.commit();
	}

	public Area getMyArea() {
		SharedPreferences settings = context.getSharedPreferences(SP_NAME, 0);
		String aid = settings.getString(SP_MY_AREA, ReleaseConfig.DEFAULT_MY_AREA);
		Area area = getOneArea(aid);
		return area;
	}

	public void getSearchOptions() {
	}

	public static JSONObject getDataComboxBox(String field, String value) {
		JSONObject result = new JSONObject();
		try {
			JSONObject options = new JSONObject(value);
			result.put(field, options);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return result;
	}

	public static JSONObject getDataRadioBox(String field, String value) {
		JSONObject result = new JSONObject();
		try {
			result.put(field, value);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return result;
	}

}
